package cn.imvc.app.models;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import cn.imvc.app.domains.GoodsState;
import cn.imvc.app.entities.Cart;
import cn.imvc.app.entities.Goods;
import cn.imvc.app.entities.GoodsPrice;
import cn.imvc.app.entities.GoodsSku;
import cn.imvc.app.entities.Member;
import cn.imvc.app.repositories.CartRepository;
import cn.imvc.app.repositories.GoodsRepository;
import cn.imvc.app.repositories.GoodsSkuRepository;
import cn.imvc.util.JSONUtils;

@Service
public class CartModelImpl implements CartModel {
	@Autowired
	private GoodsRepository goodsRepository;
	@Autowired
	private GoodsSkuRepository goodsSkuRepository;
	@Autowired
	private GoodsPriceModel goodsPriceModel;
	@Autowired
	private CartRepository cartRepository;
	@Value("${goods.defaultPriceClassCode}")
	private String defaultPriceClassCode;

	@Override
	@Deprecated
	public Cart saveInCart(Integer goodsId, Integer skuId, Member member) {
		if (member == null) {// 未登录
			// 添加到本地cookie保存

		} else {
			// 如果已经登录，直接添加到数据库

		}
		return null;
	}

	@Override
	@Deprecated
	public List<Cart> listCartItems(Member member, String cookieCartItemsStr) {
		List<Cart> cookiesCartItems = bulidCartItemsByCartItemsStr(cookieCartItemsStr, member);
		if (cookiesCartItems != null && cookiesCartItems.size() > 0) {// 若有本地缓存购物项
			cartRepository.save(cookiesCartItems);
		}
		return cartRepository.findByMemberIdAndIsBuy(member.getId(), (byte) 0);
	}

	@Override
	public Map<String, Object> updateAndListCartItems(Member member, String cookieCartItemsStr) {
		Map<String, Object> result = bulidCartItemsByCartItemsStr2(cookieCartItemsStr, member);
		List<Cart> synchronizeCarts = (List<Cart>) result.get("synchronizeCarts");
		List<Cart> delCarts = (List<Cart>) result.get("delCarts");
		if (synchronizeCarts != null && synchronizeCarts.size() > 0) {// 若有本地缓存购物项
			cartRepository.save(synchronizeCarts);
		}
		if (delCarts != null && delCarts.size() > 0) {// 删除
			for (Cart cart : delCarts) {
				if (cart.getId() != 0)
					cartRepository.deleteById(cart.getId());
			}
		}
		Map<String, Object> returnMap = new HashMap<String, Object>();
		List<Cart> carts = cartRepository.findByMemberId(member.getId());
		// String synchronizeCookieStr = (String)
		// result.get("synchronizeCookieStr");
		if (carts != null&&carts.size()>0)
			carts.sort((a, b) -> a.getGoods().getStorage().getId() - b.getGoods().getStorage().getId());
		returnMap.put("cartItems", carts);
		returnMap.put("synchronizeCookieStr", generateCookieStrByCarts(carts));
		return returnMap;

	}

	public String generateCookieStrByCarts(List<Cart> synchronizeCarts) {
		// cartId-skuId-num-isBuy-isDel
		StringBuffer sb = new StringBuffer();
		for (Cart cart : synchronizeCarts) {
			sb.append(cart.getId() + "-" + cart.getSku().getId() + "-" + cart.getGoodsNum() + "-" + cart.getIsBuy() + "-0.");
		}
		return sb.toString();
	}

	@Override
	@Deprecated
	public String saveInCookieCart(Integer goodsId, Integer skuId, Integer num) {
		Cart cart = bulidCartItem(goodsId, skuId, num, null,true);
		return JSONUtils.toJSONStringWithoutCollectionProperty(cart);
	}

	@Override
	@Deprecated
	public List<Cart> saveInDBCart(Integer goodsId, Integer skuId, Integer num, Member member, String cartItemsStr) {
		String cartStr = getCartItemsStr(cartItemsStr, goodsId, skuId, num);
		List<Cart> carts = bulidCartItemsByCartItemsStr(cartStr, member);
		cartRepository.save(carts);
		return carts;
	}

	/**
	 * 构造购物项 对象
	 * 
	 * @param goodsId
	 * @param skuId
	 * @param num
	 * @param member
	 * @param checkGift
	 * @return
	 */
	public Cart bulidCartItem(Integer goodsId, Integer skuId, Integer num, Member member,boolean checkGift) {
		GoodsSku goodsSku = goodsSkuRepository.findOne(skuId);
		if(goodsSku==null){
			return null;
		}
		byte state = goodsSku.getState();
		if(checkGift&&state==GoodsState.GIFT_STATE.getCode()){//若为赠品，且赠品检查标识为true
			return null;
		}
		if(!(state==GoodsState.GIFT_STATE.getCode()||state==GoodsState.NORMAL.getCode())){//若不为赠品，也不是正常状态
			return null;
		}
		Goods goods = goodsId == null ? goodsSku.getGoods() : goodsRepository.findOne(goodsId);
		Objects.requireNonNull(goodsSku, "goodsSku can't be null");
		Cart cart = new Cart();
		cart.setGoods(goods);
		cart.setSku(goodsSku);
		cart.setIsBuy((byte) 0);
		cart.setGoodsImage(goods.getImage());
		cart.setGoodsName(goods.getName());
		// 购买数量
		num = num == null ? new Integer(1) : num;
		cart.setGoodsNum(num);
		GoodsPrice gp = goodsPriceModel.getMemberGoodsPrices(skuId, member);
		Objects.requireNonNull(gp, "goodsPrice can't be null");
		cart.setGoodsPrice(gp.getPrice());
		cart.setMember(member);
		return cart;
	}

	@Deprecated
	public String getCartItemsStr(String cartItemsStr, Integer goodsId, Integer skuId, Integer num) {
		if (cartItemsStr != null && !"".equals(cartItemsStr)) {
			String temStr = goodsId + "-" + skuId + "-";
			// goodsId-skuid-num.goodsId-skuid-num.
			if (cartItemsStr.contains(temStr)) {// 之前已经加过该商品，之前number+这次的num
				String numStr = cartItemsStr.substring(cartItemsStr.indexOf(temStr) + temStr.length()).split("\\.")[0];
				cartItemsStr = cartItemsStr.replace(temStr + numStr, temStr + (Integer.valueOf(numStr) + num));
			} else {
				cartItemsStr = "." + temStr + num;
			}
		} else {
			cartItemsStr = goodsId + "-" + skuId + "-" + num;
		}
		return cartItemsStr;
	}

	@Deprecated
	public String changeCountOrDelCarItems(String cartItemsStr, Integer goodsId, Integer skuId, Integer num, byte optionType) {
		if (cartItemsStr != null && !"".equals(cartItemsStr)) {
			String temStr = goodsId + "-" + skuId + "-";
			// goodsId-skuid-num.goodsId-skuid-num.
			if (cartItemsStr.contains(temStr)) {// 之前已经加过该商品，之前number+这次的num
				String numStr = cartItemsStr.substring(cartItemsStr.indexOf(temStr) + temStr.length()).split("\\.")[0];
				if (optionType == 1) {// 修改数量
					cartItemsStr = cartItemsStr.replace(temStr + numStr, temStr + num);
				} else if (optionType == 2) {// 删除购物项
					if (cartItemsStr.contains("." + temStr + numStr)) {// 在中间或者结尾
						cartItemsStr = cartItemsStr.replace("." + temStr + numStr, "");
					} else if (cartItemsStr.contains(temStr + numStr + ".")) {// 在开头或者中间
						cartItemsStr = cartItemsStr.replace(temStr + numStr + ".", "");
					}
				}
			}
		}
		return cartItemsStr;
	}

	@Deprecated
	private List<Cart> bulidCartItemsByCartItemsStr(String cartItemsStr, Member member) {
		if (cartItemsStr == null || "".equals(cartItemsStr)) {
			return null;
		}
		String[] cartItems = cartItemsStr.split("\\.");
		List<Cart> carts = new ArrayList<Cart>();
		for (String item : cartItems) {
			// goodsId-skuId-num
			String[] temInfo = item.split("-");
			Cart cart = null;
			if (member != null) {
				// 验证数据库 购物车是否存在该物品 skuid and isbuy=0
				cart = cartRepository.findByMemberIdAndSkuIdAndIsBuy(member.getId(), Integer.valueOf(temInfo[1]), (byte) 0);
				if (cart != null) {// 数量加上缓存中的数量
					cart.setGoodsNum(cart.getGoodsNum() + Integer.valueOf(temInfo[2]));
				}
			}

			if (cart == null)
				cart = bulidCartItem(Integer.valueOf(temInfo[0]), Integer.valueOf(temInfo[1]), Integer.valueOf(temInfo[2]), member,true);
			carts.add(cart);
		}
		return carts;

	}

	// 修改获取购物车信息方式
	private Map<String, Object> bulidCartItemsByCartItemsStr2(String cartItemsStr, Member member) {
		Map<String, Object> result = new HashMap<String, Object>();
		// 需要同步的集合
		List<Cart> synchronizeCarts = new ArrayList<Cart>();
		// 如果id 需要删除的集合
		List<Cart> delCarts = new ArrayList<Cart>();
		result.put("synchronizeCarts", synchronizeCarts);
		result.put("delCarts", delCarts);
		if (cartItemsStr == null || "".equals(cartItemsStr)) {
			return result;
		}
		if (cartItemsStr.endsWith(".")) {
			cartItemsStr = cartItemsStr.substring(0, cartItemsStr.length() - 1);
		}
		String[] cartItems = cartItemsStr.split("\\.");
		for (String item : cartItems) {
			// cartId-skuId-num-isBuy-isDel
			String[] temInfo = item.split("-");
			Cart cart = null;
			if ("1".equals(temInfo[4])) {// 如果是删除,只需要数据库删除
				if (!StringUtils.isEmpty(temInfo[0])) {
					cart = new Cart();
					cart.setId(Integer.valueOf(temInfo[0]));
					delCarts.add(cart);
				}
				continue;
			}
			//非正常购物项状态删除
			boolean delFlag = false;
			if (member != null) {
				// 验证数据库 购物车是否存在该物品 skuid
				Integer skuId = Integer.valueOf(temInfo[1]);
				cart = cartRepository.findByMemberIdAndSkuId(member.getId(), skuId);
				if (cart != null) {
					if(cart.getSku().getState()==GoodsState.NORMAL.getCode()){
						if (!StringUtils.isEmpty(temInfo[0]) && Integer.valueOf(temInfo[0]).intValue() == cart.getId()) {// 如果有cartId说明是数据库里同步过得对象，覆盖信息
							cart.setGoodsNum(Integer.valueOf(temInfo[2]));
							cart.setGoodsPrice(goodsPriceModel.getMemberGoodsPrices(skuId, member).getPrice());
						} else {
							// 数量加上缓存中的数量
							int goodsNum = cart.getGoodsNum() + Integer.valueOf(temInfo[2]);
							cart.setGoodsNum(goodsNum);
						}
					}else{//若状态不为正常的商品，删除购物项
						delCarts.add(cart);
						delFlag = true;
					}
					// cartId-skuId-num-isBuy-isDel 只有此处cookie字符串需要同步
					// cartItemsStr =
				}

			}
			if (cart == null) {
				cart = bulidCartItem(null, Integer.valueOf(temInfo[1]), Integer.valueOf(temInfo[2]), member,true);
			}
			// 更新是否选中并添加同步列表
			if(cart!=null&&!delFlag){//不为删除的数据
				cart.setIsBuy(Byte.valueOf(temInfo[3]));
				synchronizeCarts.add(cart);
			}
		}
		if (!cartItemsStr.endsWith(".")) {
			cartItemsStr += ".";
		}
		result.put("synchronizeCookieStr", cartItemsStr);
		return result;

	}

	@Override
	public List<Cart> getCookieCartItems(String cookieCartItemsStr) {
		// return bulidCartItemsByCartItemsStr(cookieCartItemsStr, null);
		List<Cart> carts = null;
		Map<String, Object> resultMap = bulidCartItemsByCartItemsStr2(cookieCartItemsStr, null);
		if(resultMap!=null){
			carts = (List<Cart>) resultMap.get("synchronizeCarts");
			if (carts != null&&carts.size()>0)
				carts.sort((a, b) -> a.getGoods().getStorage().getId() - b.getGoods().getStorage().getId());
		}
		return carts;
	}

	@Deprecated
	@Override
	public void removeFromCart(Integer goodsId, Integer skuId, Member member) {
		Cart cart = cartRepository.findByMemberIdAndSkuIdAndIsBuy(member.getId(), skuId, (byte) 0);
		cartRepository.delete(cart);
	}

	@Deprecated
	@Override
	public void changeCartItemCount(Integer goodsId, Integer skuId, Integer num, Member member) {
		Cart cart = cartRepository.findByMemberIdAndSkuIdAndIsBuy(member.getId(), skuId, (byte) 0);
		cart.setGoodsNum(num);
		;
		cartRepository.save(cart);
	}
}
